﻿using PoliticalClassifier.Support;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace PoliticalClassifier.DataSource
{
    /// <summary>
    /// DataSetSource provides a concrete implementation of the IDataSetSource interface.
    /// </summary>
    public class DataSetSource : IDataSetSource
    {
        #region Constructor
        /// <summary>
        /// Constructs a default data set source object.
        /// </summary>
        public DataSetSource()
        {
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets the set of voter records.
        /// </summary>
        public ICollection<IVoterRecord> VotersRecord
        {
            get
            {
                return m_collectionVotersRecord;
            }
            private set
            {
                m_collectionVotersRecord = value;
            }
        }

        /// <summary>
        /// Gets whether or not the file was opened successfully.
        /// </summary>
        public bool IsFileOpenedSuccessfully
        {
            get { return m_isFileOpenedSuccessfully; }
        }

        /// <summary>
        /// Gets the number of rows that were ignored.
        /// </summary>
        public int IgnoredRowsCount
        {
            get { return m_ignoredRowsCount; }
        }

        /// <summary>
        /// Gets the names of the voter attributes.
        /// </summary>
        public string[] ColumnNames { get; private set; }
        #endregion

        #region Public Methods
        /// <summary>
        /// Loads the data from the given file path.
        /// </summary>
        /// <param name="fileName">The path of the file to load.</param>
        /// <returns>The results of the load.</returns>
        public IDataSourceLoadResults Load(String fileName)
        {
            if (!File.Exists(fileName))
                throw new FileNotFoundException("Couldn't load the file. File doesn't exists.", fileName);
            
            bool retValue;
            DataSourceLoadResults loadResults = new DataSourceLoadResults();

            try
            {
                retValue = DataSourceConnection.Open(fileName, loadResults);
                if (loadResults.CanContinue)
                {
                    if (DataSourceConnection.DataSet != null)
                    {
                        DataSet dataSet = DataSourceConnection.DataSet;
                        DataSetReader dataSetReader = new DataSetReader();

                        dataSetReader.ReadAndValidate(dataSet, loadResults);
                        m_ignoredRowsCount = dataSetReader.IgnoredRowsCount;
                        VotersRecord = dataSetReader.VotersRecord;
                        m_isFileOpenedSuccessfully = retValue;
                        ColumnNames = dataSetReader.ColumnNames;
                    }
                }
            }
            catch (Exception)
            {
                loadResults.AddError(new DataSourceUnknownError());
            }
            finally
            {
                DataSourceConnection.Close();
            }

            return loadResults;
        }

        /// <summary>
        /// Create an instance of data source load results pre-loaded with an 
        /// unknown error instance.
        /// </summary>
        /// <returns>Unknown load results.</returns>
        public IDataSourceLoadResults CreateUnknownErrorLoadResults()
        {
            IDataSourceLoadResults loadResults = new DataSourceLoadResults();
            loadResults.AddError(new DataSourceUnknownError());
            return loadResults;
        }
        #endregion

        #region Private Properties
        /// <summary>
        /// The connection to the data source.
        /// </summary>
        private IDataSourceConnection DataSourceConnection
        {
            get 
            {
                if (m_dataSourceConnection == null)
                    m_dataSourceConnection = new DataSourceConnection();

                return m_dataSourceConnection;
            }
        }
        #endregion

        #region Private Fields
        private int m_ignoredRowsCount;
        private bool m_isFileOpenedSuccessfully;
        private IDataSourceConnection m_dataSourceConnection;
        private ICollection<IVoterRecord> m_collectionVotersRecord;
        #endregion
    }
}
